/* This source code demonstrates how to connect to Access 2007
   .accdb database from C using the ODBC Data Access Technology.

   Copyright (c) Microsoft Corporation.  All rights reserved.

   This sample code is provided to illustrate a concept and 
   should not be used in applications or Web sites, as it 
   may not illustrate the safest coding practices. Microsoft 
   assumes no liability for incidental or consequential damages 
   should the sample code be used for purposes 
   other than as intended.
*/

#include <windows.h>
#include <stdio.h>
#include <sqlext.h>

/* Data Access Method used in this sample */
const char* DAM = "Direct ODBC";

/* Connection string for Direct ODBC */
char szDSN[256] = 
    "Driver={Microsoft Access Driver (*.mdb, *.accdb)};DSN='';DBQ=C:\\Northwind 2007.accdb;";

main()
{
    HENV    hEnv;
    HDBC    hDbc;

    /* ODBC API return status */
    RETCODE rc;

    int     iConnStrLength2Ptr;
    char    szConnStrOut[256];

    unsigned char* query = "SELECT Customers.[Company], Customers.[First Name] FROM Customers;";
    
    SQLCHAR         chval1[128], chval2[128], colName[128];
    int             ret1;
    int             ret2;

    /* Number of rows and columns in result set */
    SQLINTEGER      rowCount = 0;
    SQLSMALLINT     fieldCount = 0, currentField = 0;
    HSTMT           hStmt;

    /* Allocate an environment handle */
    rc = SQLAllocEnv(&hEnv);
    /* Allocate a connection handle */
    rc = SQLAllocConnect(hEnv, &hDbc);

    /* Connect to the 'Northwind 2007.accdb' database */
    rc = SQLDriverConnect(hDbc, NULL, (unsigned char*)szDSN, 
        SQL_NTS, (unsigned char*)szConnStrOut, 
        255, (SQLSMALLINT*)&iConnStrLength2Ptr, SQL_DRIVER_NOPROMPT);
    if (SQL_SUCCEEDED(rc)) 
    {
        printf("%s: Successfully connected to database. Data source name: \n  %s\n", 
           DAM, szConnStrOut);

        /* Prepare SQL query */
        printf("%s: SQL query:\n  %s\n", DAM, query);

        rc = SQLAllocStmt(hDbc,&hStmt);
        rc = SQLPrepare(hStmt, query, SQL_NTS);
       
        /* Bind result set columns to the local buffers */ 
        rc = SQLBindCol(hStmt, 1, SQL_C_CHAR, chval1, 128, (SQLINTEGER*)&ret1);
        rc = SQLBindCol(hStmt, 2, SQL_C_CHAR, chval2, 128, (SQLINTEGER*)&ret2);
       
        /* Excecute the query and create a record set */
        rc = SQLExecute(hStmt); 
        if (SQL_SUCCEEDED(rc)) 
        {
            printf("%s: Retrieve schema info for the given result set:\n", DAM);
            SQLNumResultCols(hStmt, &fieldCount);
            if (fieldCount > 0)
            {
                for (currentField=1; currentField <= fieldCount; currentField++)
                {
                    SQLDescribeCol(hStmt, currentField,
                        colName, sizeof(colName), 0, 0, 0, 0, 0);
                    printf(" | %s", colName);    
                }
                printf("\n");
            }
            else
            {
                printf("%s: Error: Number of fields in the result set is 0.\n", DAM);
            }

            printf("%s: Fetch the actual data:\n", DAM);
            /* Loop through the rows in the result set */
            rc = SQLFetch(hStmt);
            while (SQL_SUCCEEDED(rc)) 
            {
                printf(" | %s | %s\n", chval1, chval2);
                rc = SQLFetch(hStmt);
                rowCount++;
            };

            printf("%s: Total Row Count: %d\n", DAM, rowCount);
            rc = SQLFreeStmt(hStmt, SQL_DROP);
        }
    }
    else
    {
        printf("%s: Couldn't connect to %s.\n", DAM, szDSN);
    }

    /* Disconnect and free up allocated handles */
    SQLDisconnect(hDbc);
    SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
    SQLFreeHandle(SQL_HANDLE_ENV, hEnv);

    printf("%s: Cleanup. Done.\n", DAM);
}